這幾天我們已經學習了Props外來傳遞資料,還有State組件本身狀態。
今天要來學習很重要的一個使用觀念 【生命週期】。
而為甚麼我們需要了解所謂的生命週期呢???
這是因為了解組件如何被掛載和被釋放,可以使我們更能夠運用這時間差來達到獲取API或是額外的操作。
今日會學習到的Hooks
在React官方文檔中有提供我們學習類組件的生命週期
Lifecycle
Lifecycle method
依照組件的掛載與銷毀進度
constructor -> render(回傳JSX)-> componentDidUpdate -> componentWillUnmount -> componentDidMount
useEffect是React Hooks中針對生命週期的一個API
useEffect(() => {
// call
}, [dependency])
若第二個參數為空,即每次只要有組件被更新就會執行
import React,{ useEffect , useState} from 'react'
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log('changed');
})
return (
<div></div>
)
}
export default App
若第二個參數只有[ ] ,則只會執行一次
import React,{ useEffect , useState} from 'react'
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log('changed');
},[])
return (
<div></div>
)
}
export default App
若第二參數我們有指定監控的對象,即該對象更新才會執行
import React,{ useEffect , useState} from 'react'
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
console.log('changed');
},[count])
return (
<div>
<button onClick={() => setCount(count + 1) }>Click</button>
{count}
</div>
)
}
export default App
useLayoutEffect(() => {
// call
}, [dependency])
你說奇怪為什麼React要用兩個這麼像的API???
以下的code 如果把button按快一點會造成頁面的閃爍
import React,{ useEffect , useState, useLayoutEffect} from 'react'
function App() {
const [count, setCount] = useState(0)
useEffect(() => {
if(count === 0){
setCount(1)
}
},[count])
return (
<div>
<button onClick={() => setCount(0)}>Click</button>
{ count}
</div>
)
}
export default App
如果改成使用useLayoutEffect,就會很順暢並不會閃爍。
import React,{ useEffect , useState, useLayoutEffect} from 'react'
function App() {
const [count, setCount] = useState(0)
useLayoutEffect(() => {
if(count === 0){
setCount(1)
}
},[count])
return (
<div>
<button onClick={() => setCount(0)}>Click</button>
{ count}
</div>
)
}
export default App
為什麼會有以上兩種差別呢???
原因在於當我們使用useEffect狀態快速切換時會造成UI也會快速更新,進而變成畫面跟不上我們點擊的速度。
而如果是使用useLayoutEffect的話,相當於在UI更新前已經先執行好更新狀態,所以狀態提前被準備好。
我們看了官方的文檔之後,解釋為同步於DOM更新
然而大部分的場景useEffect其實就可以完成我們的工作。